#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json

import sys
import tornado.web
import uuid
import md5
import string
import base64
import time
import datetime
import memcache
from controls import data_user_detail_mysql
from controls import data_user_brief_mysql
from config import etc
from utils import util
from utils import session_base
from utils import log
 

def generate_uuid( ) :
    return str(uuid.uuid4())


def make_session_id(st):
    m = md5.new()
    m.update(str(time.time()))
    m.update(str(st))
    return string.replace(base64.encodestring(m.digest())[:-3], '/', '$')


def set_mc(mkey, value, timeout=etc.session_timeout):
    try:
        mc = memcache.Client(etc.memcached_addr, debug=0)
        if mc.set(mkey, value, timeout):
            return True
        return False
    except Exception as e:
        log.exp(e)
        return False


def get_mc(mkey):
    try:
        mc = memcache.Client(etc.memcached_addr, debug=0)
        value = mc.get(mkey)
        return value
    except Exception as e:
        log.exp(e)
        return None


def delete_mc(mkey) :
    try:
        mc = memcache.Client(etc.memcached_addr, debug=0)
        if mc.delete(mkey, 0):
            return True
        return False
    except Exception as e:
        log.exp(e)
        return False


def replace_mc(mkey, value, timeout=etc.session_timeout):
    try:
        mc = memcache.Client(etc.memcached_addr, debug=0)
        if mc.replace(mkey, value, timeout):
            return True
        return False
    except Exception as e:
        log.exp(e)
        return False


def set_ss( ssid, ss_user ) :
    try:
        raw_data = util.encode( ss_user )
        mc = memcache.Client( etc.memcached_addr, debug=0 )
        if mc.set( 'ss_'+ssid, raw_data, etc.session_timeout ) :
            return True
        return False
    except Exception as e:
        log.exp(e)
        return False


def get_ss( ssid ) :
    try:
        mc = memcache.Client( etc.memcached_addr, debug=0 )
        raw_data = mc.get( 'ss_'+ssid )
        ss_user = None
        if raw_data :
            ss_user = util.decode( raw_data )
        return ss_user
    except Exception as e:
        log.exp(e)
        return None


def delete_ss( ssid ) :
    try:
        mc = memcache.Client( etc.memcached_addr, debug=0 )
        if mc.delete( 'ss_'+ssid, 0 ) :
            return True
        return False
    except Exception as e:
        log.exp(e)
        return False


def replace_ss( ssid, ss_user ) :
    try:
        raw_data = util.encode( ss_user )
        mc = memcache.Client( etc.memcached_addr, debug=0 )
        if mc.replace( 'ss_'+ ssid, raw_data, etc.session_timeout ) :
            return True
        return False
    except Exception as e:
        log.exp(e)
        return False


class McSessionStore( session_base.BaseSessionStore ) :

    def contains( self, key ) :
        raise NotImplementedError

    def cleanup( self ) :
        raise NotImplementedError

    def get( self, ssid ) :
        return get_ss( ssid )

    def set( self, ssid, ss_user ) :
        return set_ss( ssid, ss_user )

    def delete( self, ssid ) :
        return delete_ss( ssid )

    def replace( self, ssid, ss_user ) :
        return replace_ss( ssid, ss_user )


# one point login
class McBaseStore(session_base.BaseSessionStore):
    PREFIXES = ['login', 'cmslogin']

    def __init__(self, prefix='', timeout=etc.session_timeout):
        self.prefix = prefix
        self.timeout = timeout

    def contains(self, key):
        raise NotImplementedError

    def cleanup(self):
        raise NotImplementedError

    def get(self, mkey):
        return get_mc(self.prefix + str(mkey))

    def set(self, mkey, value):
        return set_mc(self.prefix + str(mkey), value, self.timeout)

    def delete(self, mkey):
        return delete_mc(self.prefix + str(mkey))

    def replace(self, mkey, value):
        return replace_mc(self.prefix + str(mkey), value, self.timeout)


class McVerifyStore(session_base.BaseSessionStore):
    prefix = 'verify'
    timeout = 1800

    def contains(self, key):
        raise NotImplementedError

    def cleanup(self):
        raise NotImplementedError

    def get(self, mkey):
        v_l = get_mc(self.prefix + str(mkey))
        v_list = []
        if v_l:
            v_list = v_l.split("#")
        return v_list

    def set(self, mkey, value_list):
        value = '#'.join(value_list)
        return set_mc(self.prefix + str(mkey), value, self.timeout)

    def add(self, mkey, value):
        old_v = get_mc(self.prefix + str(mkey)) or ''
        value = '#'.join([old_v.strip('#'), value])
        return set_mc(self.prefix + str(mkey), value, self.timeout)

    def delete(self, mkey):
        return delete_mc(self.prefix + str(mkey))

    def replace(self, mkey, value_list):
        value = '#'.join(value_list)
        return replace_mc(self.prefix + str(mkey), value, self.timeout)


class BaseHandler( tornado.web.RequestHandler ) :

    def initialize( self ):
        self.ss_store = McSessionStore()
        self.ss_user = None
        return

    def write_error( self, status_code, **kwargs ) :
        self.render( '503.html' )

    def plant_ssid( self ) :
        try:
            self.ssid = self.get_cookie( etc.cookie_ssid )
            if not self.ssid :
                expires = datetime.datetime.utcnow() + datetime.timedelta(days=365)
                ssid = generate_uuid()
                domain = util.get_domain_from_host( self.request.host )
                self.set_cookie( etc.cookie_ssid, ssid, domain=domain, expires=expires )
                self.ssid = ssid
        except Exception as e:
            log.exp(e)

    def get_current_user(self):
        try:
            log.i('---------start get_current_user-------------------')
            cookie_check = self.get_secure_cookie(etc.cookie_check)
            cookie_verify = self.get_secure_cookie(etc.cookie_verify)
            if not cookie_check or not cookie_verify:
                log.i('no cookie check or verify')
                self.clear_cookie(etc.cookie_check)
                self.clear_cookie(etc.cookie_verify)
                self.ss_user = None
                return None
            check_verify = session_base.generate_hmac(cookie_check)
            if cookie_verify != check_verify:
                log.w("evil session : %s %s"%(cookie_check, cookie_verify))
                self.clear_cookie(etc.cookie_check)
                self.clear_cookie(etc.cookie_verify)
                self.ss_user = None
                return None
            old_ss_user = self.ss_store.get( cookie_check )
            if old_ss_user is None:
                log.i("session expired")
                self.clear_cookie( etc.cookie_check )
                self.clear_cookie( etc.cookie_verify )
                self.ss_user = None
                return None
            self.ss_user = old_ss_user

            log.i("---------self.ss_user=%s -------------" % self.ss_user)
            return self.ss_user
        except Exception as e:
            log.exp(e)
            self.clear_cookie(etc.cookie_check)
            self.clear_cookie(etc.cookie_verify)
            self.ss_user = None
            return self.ss_user

    def generate_res(self, condition, ret_num, msg, step_name=''):
        """

        :param right: bool, true or false
        :param ret_num: ret
        :param msg: message
        :param step_name: for log
        :return: not pass True, pass False
        """
        if not condition:
            log.w(step_name)
            ret = {
                'idx': self.ss_idx,
                'ret': ret_num,
                'res': {},
                'msg': msg
            }
            log.i(step_name + 'error')
            self.write(json.dumps(ret))
            self.finish()
            return True
        return False

    def _generate_res(self, ret_num, msg, step_name=''):
        log.w(step_name)
        ret = {
            'idx': self.ss_idx,
            'ret': ret_num,
            'res': {},
            'msg': msg
        }
        log.i(step_name + 'error')
        self.write(json.dumps(ret))
        self.finish()


def login(handler, user_base, expires):
    if not handler.ss_user:
        user_detail = data_user_detail_mysql\
            .get_user_detail_by_userid(user_base['userid'])
        user_brief = data_user_brief_mysql\
            .get_user_brief_by_userid(user_base['userid'])
        orig_dict = {
            'name': '',
            'sex': '',
            'sexot': '',
            'love': '',
            'horo': '',
            'intro': '',
            'zone': '',
            'imglink': '',
        }
        handler.ss_user = {
            'ssid': handler.ssid,
            'userid': user_base['userid'],
            # 'email': user_base['email'],
            'phone': user_base['phone'],
        }

        log.i('before update(orig_dict)=========%s=========' % handler.ss_user)

        handler.ss_user.update(orig_dict)
        if user_detail:
            handler.ss_user.update(user_detail)

        log.i('after update(detail)=========%s=========' % handler.ss_user)

        if user_brief:
            handler.ss_user.update(user_brief)

        log.i('after update(brief)=========%s=========' % handler.ss_user)

    # else :
    #     ss_others = data_user_base_mysql.(
    #     for ss_other in ss_others :
    #         ss_user = self.ss_store.get( ss_other )

    # delete old ssid. one point login
    one_login_store = McBaseStore(McBaseStore.PREFIXES[0])
    old_ssid = one_login_store.get(user_base['userid'])

    log.i('refresh ssid in mc old_ssid=%s handler.ssid=%s' % (old_ssid, handler.ssid))
    one_login_store.set(user_base['userid'], handler.ssid)

    if handler.ssid != old_ssid:
        log.i('delete old ssid if handler.ssid is not old ssid')
        handler.ss_store.delete(old_ssid)

    domain = util.get_domain_from_host(handler.request.host)
    handler.ssid_hmac = session_base.generate_hmac(handler.ssid)
    handler.set_secure_cookie(etc.cookie_check, handler.ssid, domain=domain, expires=expires)
    handler.set_secure_cookie(etc.cookie_verify, handler.ssid_hmac, domain=domain, expires=expires)
    handler.ss_store.set(handler.ssid, handler.ss_user)

def logout(handler):
    handler.clear_all_cookies()
    # self.ss_user = self.ss_store.get(self.ssid)
    if handler.ss_user:
        log.i('userid=%s , ssid=%s' % (handler.ss_user['userid'], handler.ssid))
        handler.ss_store.delete(handler.ssid)
        # delete old ssid. one point login
        one_login_store = McBaseStore(McBaseStore.PREFIXES[0])
        one_login_store.delete(handler.ss_user['userid'])

    handler.ss_user = None


if __name__ == "__main__":
    key='None'
    try:
        key = str(sys.argv[1])
    except Exception as e:
        print e
        exit(1)

    #不管是否连接成功，这里都不会异常;
    mc = memcache.Client( etc.memcached_addr, debug=0 )

    #如果异常,op=0; 如果正常,op=True;
    #op = mc.set(key,"yexiang")
    #print op

    #如果异常,res=None;
    res = mc.get(key)

    print key
    print res


